﻿Imports st = System.Text
Imports System.DateTime
Imports System.IO
Imports System.IO.Compression
Imports sxl = System.Xml.Linq
Imports System.Linq
Imports bw = beyonWizUpdater

Public Class wizScheduleCheckerMain

    ' Dim tv As tvGuideListing  code analy said not used
    Dim webTvGuide As ozTivoListing = New ozTivoListing
    Dim beyonWizA As bwAccessor
    Dim beyonWizTimerList As List(Of scheduledEvent) = New List(Of scheduledEvent)


    Private Sub wizScheduleChecker_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'config.loadConfig() 'new oztivo causes this
        config.getAll(ipAddress.Text, refreshDays.Text, noOfDaysToDownload.Text, noTimers.Text, tvListingDirectory.Text, ozTivoUserName.Text, ozTivoPassword.Text, Me.fromEmail.Text, Me.toEmail.Text, Me.emailSubject.Text, Me.emailUserId.Text, Me.emailPassword.Text, Me.serverHost.Text, Me.serverPort.Text, Me.ratingsThreashold.Text)

        For Each t As Integer In config.channelList.Keys
            serviceList.Rows.Add(config.channelList.Item(t).toParamArray)
        Next

        For Each p As String In config.progWatchList
            WatchList.Rows.Add(createDataGridRow(p, ""))
        Next

        For Each c As String In config.catWatchList
            categoryList.Rows.Add(createDataGridRow(c, ""))
        Next
        Me.Visible = True
        System.Windows.Forms.Application.DoEvents()

        Me.updateStatus("checking timers ", "")
        btnCheckTimer_Click(Nothing, Nothing)

        If My.Application.CommandLineArgs.Count > 0 Then

            Me.updateStatus("Removing conflicts ", "")
            If btnFixConflicts_Click(Nothing, Nothing) Then

                Me.updateStatus("Writing timers ", "")
                cmdWriteTimers_Click(Nothing, Nothing)
            End If
            Me.Close()
        End If

    End Sub

    Private Sub wizScheduleChecker_Closing(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.FormClosing
        saveConfig()

    End Sub

    Private Sub btnCheckTimer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCheckTimer.Click
        Dim connectionSuccessful As Boolean = True

        If ipAddress.Text <> "" Then
            statusBar.Text = "Getting BeyonWiz timers from " & ipAddress.Text
            System.Windows.Forms.Application.DoEvents()
            beyonWizA = New bwAccessor()
            Try
                beyonWizTimerList.Clear()
                beyonWizTimerList = beyonWizA.GetTimers(ipAddress.Text, telnetCommand.Text)
            Catch ex As Exception
                connectionSuccessful = False
                MsgBox(ex.Message)
            End Try
            If connectionSuccessful Then
                statusBar.Text = "Adding any unknown channels "
                System.Windows.Forms.Application.DoEvents()
                Dim dodgyServices = (From x In beyonWizTimerList Where x.issueText = "Unknown Channel" Select New svc With {.channelId = x.svcId, .channelName = "Unknown", .onId = x.onId, .tsId = x.tsId}).ToList.Distinct

                For Each dodgyChannel As svc In dodgyServices
                    serviceList.Rows.Add(dodgyChannel.toParamArray())
                Next
            End If
        End If

        statusBar.Text = "Adding any repeat programs to watch list "
        System.Windows.Forms.Application.DoEvents()

        Dim repeatProgs = From bwtle In beyonWizTimerList Where bwtle.repeat <> "0" Select p = bwtle.progName, r = bwtle.repeat Distinct

        config.progWatchList = (From progWatchListDGRow As DataGridViewRow In WatchList.Rows
                                                Where progWatchListDGRow.Cells(0).Value <> ""
                                                Let x As String = progWatchListDGRow.Cells(0).Value
                                                Select x).ToList

        For Each repeats As Object In repeatProgs
            If Not config.progWatchList.Contains(repeats.p) Then
                WatchList.Rows.Add(createDataGridRow(repeats.p, repeats.r))
            End If
        Next

        statusBar.Text = "Refreshing watch list after updates"
        System.Windows.Forms.Application.DoEvents()

        config.progWatchList = (From progWatchListDGRow As DataGridViewRow In WatchList.Rows
                         Where (progWatchListDGRow.Cells(0).Value <> "")
                         Let x As String = progWatchListDGRow.Cells(0).Value
                         Select x.ToUpper).ToList

        statusBar.Text = "Getting OzTivo Guide"
        System.Windows.Forms.Application.DoEvents()
        webTvGuide.loadTvProgramListings()

        timerConflicts.determineTimerIssues(webTvGuide, beyonWizTimerList, config.progWatchList)

        'timerConflicts.identifyConflicts(webTvGuide, beyonWizTimerList, config.progWatchList)

        showOutput()

        'fixup()

    End Sub

    Public Sub fixupChannelDetails()
        Dim f2 As List(Of svc) = (From bwtl As scheduledEvent In beyonWizTimerList
                                  Select New svc With {.channelId = bwtl.svcId, .channelName = bwtl.channel, .onId = bwtl.onId, .tsId = bwtl.tsId}).ToList

        For Each r As DataGridViewRow In serviceList.Rows
            If r.Cells(2).Value = "" Then
                Dim x As svc = (From z As svc In f2 Where z.channelId = r.Cells(0).Value Select z).FirstOrDefault
                If Not x Is Nothing Then
                    r.Cells(2).Value = x.onId
                    r.Cells(3).Value = x.tsId
                End If
            End If
        Next
    End Sub

    Private Sub cmdWriteTimers_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdWriteTimers.Click
        Dim bwu As New bw.beyonWizUpdater
        bwu.thing = beyonWizTimerList

        Dim b As Boolean = bwu.Writetimers(ipAddress.Text, True)
        statusBar.Text = "Done"
        System.Windows.Forms.Application.DoEvents()
    End Sub

    Private Sub filterCB_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles filterCB.CheckedChanged
        showOutput()
    End Sub
    Private Sub showOutput()
        Me.updateStatus("Displaying results ", "")
        If beyonWizTimerList Is Nothing Then Exit Sub

        statusBar.Text = "Ouput results"
        System.Windows.Forms.Application.DoEvents()

        Dim goodStyle As New DataGridViewCellStyle
        goodStyle.BackColor = Color.Green

        Dim timerError As New DataGridViewCellStyle
        timerError.BackColor = Color.Red

        Dim timerWarning As New DataGridViewCellStyle
        timerWarning.BackColor = Color.Orange

        Dim timerConflict As New DataGridViewCellStyle
        timerConflict.BackColor = Color.Brown

        Dim recommended As New DataGridViewCellStyle
        recommended.BackColor = Color.Blue

        Dim beyonWizTimerSortedList = (From b As scheduledEvent In beyonWizTimerList Order By b.startTime, b.progName Select b)

        bwTimerGrid.Rows.Clear()
        For Each t As scheduledEvent In beyonWizTimerSortedList
            Dim bwr As Int16 = bwTimerGrid.Rows.Add(t.parmArray)
            bwTimerGrid.Rows(bwr).Tag = t       'establish link to the event being displayed
            bwTimerGrid.Rows(bwr).Cells(0).Value = "Delete"
            Select Case t.issueCategory
                Case "G"
                    bwTimerGrid.Rows(bwr).Cells(1).Style = goodStyle
                Case "WGG" 'Warning CHANNEL (6), Good PROG NAME (2), Good DATE (3 & 4)
                    bwTimerGrid.Rows(bwr).Cells(1).Style = timerWarning
                    bwTimerGrid.Rows(bwr).Cells(6).Style = timerWarning
                Case "GWG"
                    bwTimerGrid.Rows(bwr).Cells(1).Style = timerWarning
                    bwTimerGrid.Rows(bwr).Cells(2).Style = timerWarning
                Case "GGW"
                    bwTimerGrid.Rows(bwr).Cells(1).Style = timerWarning
                    bwTimerGrid.Rows(bwr).Cells(3).Style = timerWarning
                    bwTimerGrid.Rows(bwr).Cells(4).Style = timerWarning
                Case "GWW"
                    bwTimerGrid.Rows(bwr).Cells(1).Style = timerWarning
                    bwTimerGrid.Rows(bwr).Cells(2).Style = timerWarning
                    bwTimerGrid.Rows(bwr).Cells(3).Style = timerWarning
                    bwTimerGrid.Rows(bwr).Cells(4).Style = timerWarning
                Case "WWG"
                    bwTimerGrid.Rows(bwr).Cells(1).Style = timerWarning
                    bwTimerGrid.Rows(bwr).Cells(6).Style = timerWarning
                    bwTimerGrid.Rows(bwr).Cells(2).Style = timerWarning
                Case "E"
                    bwTimerGrid.Rows(bwr).Cells(1).Style = timerError
                Case "R"
                    bwTimerGrid.Rows(bwr).Cells(1).Style = recommended
                Case "C"
                    bwTimerGrid.Rows(bwr).Cells(1).Style = timerConflict
            End Select
        Next

        WebListings.Rows.Clear()
        For Each channelListing As tvGuideListing In webTvGuide.tvGuideListings_List
            For Each t As scheduledEvent In channelListing.tvGuideScheduledEventsList

                If Not filterCB.Checked Or t.issueText <> "" Then
                    Dim wlr As Int16 = WebListings.Rows.Add(t.parmArray)
                    WebListings.Rows(wlr).Tag = t                       'establish link to the event being displayed
                    WebListings.Rows(wlr).Cells(0).Value = "Record"
                    If t.issueText Is Nothing Then Continue For
                    Select Case t.issueCategory
                        Case "G"
                            WebListings.Rows(wlr).Cells(1).Style = goodStyle

                        Case "WGG" 'Warning CHANNEL (6), Good PROG NAME (2), Good DATE (3 & 4)
                            WebListings.Rows(wlr).Cells(1).Style = timerWarning
                            WebListings.Rows(wlr).Cells(6).Style = timerWarning
                        Case "GWG"
                            WebListings.Rows(wlr).Cells(1).Style = timerWarning
                            WebListings.Rows(wlr).Cells(2).Style = timerWarning
                        Case "GGW"
                            WebListings.Rows(wlr).Cells(1).Style = timerWarning
                            WebListings.Rows(wlr).Cells(3).Style = timerWarning
                            WebListings.Rows(wlr).Cells(4).Style = timerWarning
                        Case "GWW"
                            WebListings.Rows(wlr).Cells(1).Style = timerWarning
                            WebListings.Rows(wlr).Cells(2).Style = timerWarning
                            WebListings.Rows(wlr).Cells(3).Style = timerWarning
                            WebListings.Rows(wlr).Cells(4).Style = timerWarning
                        Case "WWG"
                            WebListings.Rows(wlr).Cells(1).Style = timerWarning
                            WebListings.Rows(wlr).Cells(6).Style = timerWarning
                            WebListings.Rows(wlr).Cells(2).Style = timerWarning
                        Case "E"
                            WebListings.Rows(wlr).Cells(1).Style = timerError
                        Case "R"
                            WebListings.Rows(wlr).Cells(1).Style = recommended
                        Case "C"
                            WebListings.Rows(wlr).Cells(1).Style = timerConflict
                    End Select
                End If
            Next t
        Next
        updateStatus("Done - ", Now())
    End Sub

    Private Sub btnSaveServiceNames_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSaveServiceNames.Click
        saveConfig()
    End Sub

    Private Sub saveConfig()
        config.channelList.Clear()
        For Each r As DataGridViewRow In serviceList.Rows
            If r.Cells(0).Value <> 0 And r.Cells(1).Value <> "" Then config.channelList.Add(r.Cells(0).Value, New svc(r.Cells(0).Value, r.Cells(1).Value, r.Cells(2).Value, r.Cells(3).Value))
        Next
        config.progWatchList.Clear()
        For Each r As DataGridViewRow In WatchList.Rows
            If r.Cells(0).Value Is Nothing Then Continue For
            config.progWatchList.Add(r.Cells(0).Value)
        Next

        config.catWatchList.Clear()
        For Each r As DataGridViewRow In categoryList.Rows
            If r.Cells(0).Value Is Nothing Then Continue For
            config.catWatchList.Add(r.Cells(0).Value)
        Next

        config.setAll(Me.ipAddress.Text, Me.refreshDays.Text, Me.noOfDaysToDownload.Text, Me.noTimers.Text, Me.tvListingDirectory.Text, Me.ozTivoUserName.Text, Me.ozTivoPassword.Text, Me.fromEmail.Text, Me.toEmail.Text, Me.emailSubject.Text, Me.emailUserId.Text, Me.emailPassword.Text, Me.serverHost.Text, Me.serverPort.Text, Me.ratingsThreashold.Text)
        config.saveConfig()
    End Sub

    Private Function createDataGridRow(ByVal cellA As String, ByVal cellB As String) As String()
        Dim pa(3) As String
        pa(0) = cellA
        pa(1) = cellB
        Return pa

    End Function

    Public Sub updateStatus(ByVal text As String, ByVal details As String)
        statusBar.Text = text & details
        System.Windows.Forms.Application.DoEvents()
    End Sub

    Private Sub WebListings_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles WebListings.CellContentClick
        'if the add button is clicked then have to add an entry to the beyon wiz timer list and data grid
        If e.ColumnIndex <> 0 Then Exit Sub
        For Each r As DataGridViewRow In WebListings.Rows
            If r.Cells(0).Selected Then
                Dim tempSE As scheduledEvent = timerConflicts.addEventAndCheckConflict(beyonWizTimerList, config.progWatchList, r.Tag, "New Prog - ")
                If tempSE.issueCategory = "C" Then r.Cells(1).Style.BackColor = Color.Brown
            End If
        Next
        timerConflicts.determineTimerIssues(webTvGuide, beyonWizTimerList, config.progWatchList)

        showOutput()
    End Sub

    Private Sub bwTimerList_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles bwTimerGrid.CellContentClick
        'if the add button is clicked then have to remove the entry from the beyonwiz timer list list and data grid
        If e.ColumnIndex <> 0 Then Exit Sub
        For Each r As DataGridViewRow In bwTimerGrid.Rows
            If r.Cells(0).Selected Then
                Dim s As scheduledEvent = r.Tag
                beyonWizTimerList.Remove(s)
                'bwTimerList.Rows.Remove(r)
            End If
        Next
        timerConflicts.determineTimerIssues(webTvGuide, beyonWizTimerList, config.progWatchList)
        'timerConflicts.identifyConflicts(webTvGuide, beyonWizTimerList, config.progWatchList)

        showOutput()
    End Sub


    Private Function btnFixConflicts_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles fixConflicts.Click
        Dim rebootNeeded As Boolean = False
        Dim fixList As String
        fixList = fixList & " ------------------------------------------------------------------------------------------------" & vbLf
        fixList = fixList & " ---------------------------T-i-m-e-r-s---N-e-e-d-i-n-g--R-e-m-o-v-a-l---------------------------" & vbLf
        fixList = fixList & " ------------------------------------------------------------------------------------------------" & vbLf & vbLf

        'can't remove entries from list that controls the loop, therefore I'll do it first.
        For Each t As scheduledEvent In (From x In beyonWizTimerList Where x.issueCategory = "E" Or x.issueCategory = "C" Select x).ToList
            fixList = fixList & "Remove: " & t.progName & " on channel " & t.channel & " starting " & t.startTime & " finishing " & t.stopTime & " because " & t.issueText & vbLf
            Me.updateStatus("Removing conflicts ", t.progName)
            beyonWizTimerList.Remove(t)
            rebootNeeded = True
        Next

        fixList = fixList & " ------------------------------------------------------------------------------------------------" & vbLf
        fixList = fixList & " ---------------------------T-i-m-e-r-s---N-e-e-d-i-n-g--F-i-x-i-n-g------------------------------" & vbLf
        fixList = fixList & " ------------------------------------------------------------------------------------------------" & vbLf & vbLf

        For Each t As scheduledEvent In beyonWizTimerList
            If t.issueCategory = "R" Then Continue For
            Me.updateStatus("Adjusting details for ", t.progName)
            Select Case t.issueCategory
                Case "WGG" 'Warning CHANNEL (6), Good PROG NAME (2), Good DATE (3 & 4)
                    fixList = fixList & "Change Channel to " & t.ozTivoEquivalent.channel & " on " & t.progName & " on channel " & t.channel & " starting " & t.startTime & " finishing " & t.stopTime & " because " & t.issueText & vbLf
                    t.channel = t.ozTivoEquivalent.channel
                    rebootNeeded = True
                Case "GWG"
                    fixList = fixList & "Change program name to " & t.ozTivoEquivalent.progName & " on " & t.progName & " on channel " & t.channel & " starting " & t.startTime & " finishing " & t.stopTime & " because " & t.issueText & vbLf
                    t.progName = t.ozTivoEquivalent.progName
                    rebootNeeded = True
                Case "GGW"
                    fixList = fixList & "Change start/ stop time to " & t.ozTivoEquivalent.startTime & "/" & t.ozTivoEquivalent.stopTime & " on " & t.progName & " on channel " & t.channel & " starting " & t.startTime & " finishing " & t.stopTime & " because " & t.issueText & vbLf
                    t.startTime = t.ozTivoEquivalent.startTime
                    t.startTime = t.ozTivoEquivalent.stopTime
                    t.progLength = t.ozTivoEquivalent.progLength
                    t.duration = t.ozTivoEquivalent.duration
                    rebootNeeded = True
                Case "GWW"
                    fixList = fixList & "Change program name to " & t.ozTivoEquivalent.progName & vbLf
                    fixList = fixList & "And Change start/ stop time to " & t.ozTivoEquivalent.startTime & "/" & t.ozTivoEquivalent.stopTime & " on " & t.progName & " on channel " & t.channel & " starting " & t.startTime & " finishing " & t.stopTime & " because " & t.issueText & vbLf
                    t.progName = t.ozTivoEquivalent.progName
                    t.startTime = t.ozTivoEquivalent.startTime
                    t.startTime = t.ozTivoEquivalent.stopTime
                    t.progLength = t.ozTivoEquivalent.progLength
                    t.duration = t.ozTivoEquivalent.duration
                    rebootNeeded = True
                Case "WWG"
                    fixList = fixList & "Change Channel to " & t.ozTivoEquivalent.channel
                    fixList = fixList & "And Change program name to " & t.ozTivoEquivalent.progName & " on " & t.progName & " on channel " & t.channel & " starting " & t.startTime & " finishing " & t.stopTime & " because " & t.issueText & vbLf
                    t.channel = t.ozTivoEquivalent.channel
                    t.progName = t.ozTivoEquivalent.progName
                    rebootNeeded = True
            End Select
            t.issueCategory = "G"
            If Not t.ozTivoEquivalent Is Nothing Then t.ozTivoEquivalent.issueCategory = "G"
        Next

        fixList = fixList & " ------------------------------------------------------------------------------------------------" & vbLf
        fixList = fixList & " ---------------------------A-d-d-i-n-g--W-a-t-c-h-l-i-s-t--R-e-c-o-m-e-n-d-a-t-i-o-n-s----------" & vbLf
        fixList = fixList & " ------------------------------------------------------------------------------------------------" & vbLf & vbLf

        For Each t As scheduledEvent In beyonWizTimerList
            If t.issueCategory = "R" Then
                fixList = fixList & "Add: " & t.progName & " on channel " & t.channel & " starting " & t.startTime & " finishing " & t.stopTime & " because " & t.issueText & vbLf
                rebootNeeded = True
            End If
        Next

        showOutput()
        email.sendEmail(config.fromEmail, config.toEmail, config.emailSubject, fixList)
        Return rebootNeeded
    End Function

    Private Sub cmdQuit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdQuit.Click
        Me.Close()
    End Sub

End Class